// 路由守卫废弃了next函数的用法，使用return的方式 allow guards to return a value instead of calling next
// 参考 https://github.com/vuejs/rfcs/blob/master/active-rfcs/0037-router-return-guards.md#motivation

import router from '@/router'
import store from '@/store'
import NProgress from 'nprogress' // Progress 进度条
import 'nprogress/nprogress.css' // Progress 进度条样式
import { ElMessage } from 'element-plus'
import { getToken } from '@/api/login' // 验权
import Layout from '@/views/layout/frame/Layout.vue' // Layout
import { getMenuByCurrentUser } from '@/api/menu' // getFindByCurrentUser
import { getUserProject } from '@/api/user'

import { getCurTenant, removeCurTenant, getCurrentTenantList } from '@/api/tenant'

import { getCurUserBtnPerms } from '@/api/permission'
NProgress.configure({ showSpinner: false }) // NProgress Configuration n进程配置

// 权限判断函数
function hasPermission(roles, permissionRoles) {
  if (roles.indexOf('SYS_ADMIN') >= 0) return true // admin 管理员权限直接通过
  if (!permissionRoles) return true
  return roles.some(role => permissionRoles.indexOf(role) >= 0)
}

// const _import = require('./router/_import_' + process.env.NODE_ENV)// 获取组件的方法
const _import = file => () => import('@/views/' + file + '.vue')

const whiteList = ['/login', '/resetPassword', '/requestResetPwd'] // 不重定向白名单 /realTimeAlarm , '/eventAlarm/historyAlarm', '/scada', '/phonePage'
// let getRouter = [] // 用来获取后台拿到的路由
let getRouter: any[] | null = null // 用来获取后台拿到的路由
let btnPerms = null // 用来获取后台拿的按钮权限列表

router.beforeEach(async to => {
  NProgress.start()
  if (getToken()) {
    if (to.path === '/login') {
      if ((store.state as any).permission.addRouters.length === 0) {
        return { path: '/' }
      } else {
        // 自定义iframe大屏
        let path = ''
        if ((store.state as any).permission.bigScreenR[0]) {
          path = (store.state as any).permission.bigScreenR[0].path
        } else {
          const path1 = (store.state as any).permission.addRouters[0].path
          const path2 = (store.state as any).permission.addRouters[0].children[0].path
          path = path1 + '/' + path2
        }
        return { path: path }
      }
      NProgress.done() // 如果当前页面是仪表板，则不会在每个钩子之后触发，因此手动处理它。
    } else {
      console.log(store.getters.roles, getRouter)

      if (store.getters.roles.length === 0 || !getRouter) {
        // 判断当前用户是否已拉取完user_info信息
        store
          .dispatch('user/GetInfo')
          .then(async res => {
            // 拉取用户信息
            const roles = [res.data.authority]
            // 注意：角色必须是数组！如：['editor','develop']
            if (!btnPerms) {
              getCurUserBtnPerms().then(res => {
                btnPerms = res.data // 后台拿到路由
                store.dispatch('permission/SetCurUserBtnPerms', btnPerms)
              })
            }
            if (!getRouter) {
              // 根据当前登录角色判断是否获取扩展菜单

              roles.forEach(async v => {
                if (v === 'SYS_ADMIN') {
                  removeCurTenant() // 不需要企业切换
                  getRouter = []
                  store.dispatch('permission/GenerateRoutes', { roles, getRouter }).then(() => {
                    // 根据roles权限生成可访问的路由表
                    store.getters.addRouters.forEach(item => router.addRoute(item))
                    console.log(router.getRoutes(), 'router.getRoutes()')
                    router.replace({ ...to, replace: true })
                  })
                } else if (v === 'CUSTOMER_USER' || v === 'TENANT_ADMIN') {
                  removeCurTenant() // 不需要企业切换
                  getMenuByCurrentUser().then(async res => {
                    getRouter = res.data // 后台拿到路由
                    const route = await routerGo(roles, to) // 处理取到的路由后 执行路由跳转方法
                    router.replace(route)
                  })
                } else if (v === 'TENANT_SUPPORT' || v === 'TENANT_PROMOTE') {
                  console.log(store)
                  if (!getCurTenant() || !(store.state as any).user.tenantList.length) {
                    // 当前是否有企业
                    const res = await getCurrentTenantList()
                    // console.log(res, 'getCurrentTenantList')
                    await store.dispatch('user/etTenantList', res.data)
                  }
                  const res = await getMenuByCurrentUser()
                  getRouter = res.data // 后台拿到路由
                  const route = await routerGo(roles, to) // 处理取到的路由后 执行路由跳转方法
                  router.replace(route)
                }
              })
            } else {
              const route = await routerGo(roles, to) // 处理取到的路由后 执行路由跳转方法
              router.replace(route)
            }
          })
          .catch(err => {
            store.dispatch('user/FedLogOut').then(() => {
              ElMessage.error(err || '验证失败，请重试')
              return { path: '/' }
            })
          })
      } else {
        if (hasPermission(store.getters.roles, to.meta.roles)) {
          if (store.getters.roles[0] === 'CUSTOMER_USER') {
            if (
              (store.state as any).app.projectRole &&
              (store.state as any).app.projectRole.length > 0
            ) {
              return true
            } else {
              const userProject = await getUserProject((store.state as any).user.id)
              const projectD: any[] = []
              for (const item of userProject.data) {
                projectD.push(item.id)
              }

              store.dispatch('user/SetUserProject', { pData: projectD, isSet: true })
              return true
            }
          } else {
            // return { ...to }
            return true
          }
        } else {
          return { path: '/404', replace: true }
          // next('/404')
        }
      }
    }
  } else {
    /* has no token*/
    if (whiteList.indexOf(to.path) !== -1 || to.path.substr(0, 7) === '/login/') {
      // 在免登录白名单，直接进入
      return true
    } else {
      NProgress.done() // 如果当前页面是登录，则不会触发每个钩子，所以手动处理它
      return { path: '/login', replace: true }
    }
  }
})

async function routerGo(roles, to) {
  getRouter = filterAsyncRouter(getRouter) // 过滤路由
  await store.dispatch('permission/GenerateRoutes', { roles, getRouter })
  // 根据roles权限生成可访问的路由表
  store.getters.addRouters.forEach(item => router.addRoute(item))

  // router.addRoute(store.getters.addRouters) // 动态添加可访问路由表

  return { ...to, replace: true } // hack方法 确保addRoutes已完成 ,设置replace: true，这样导航不会留下历史记录
}

function filterAsyncRouter(extendRouterMap) {
  // 遍历后台传来的路由字符串，转换为组件对象
  const extendRouters = extendRouterMap.filter(route => {
    if (route.component) {
      if (route.component === 'Layout') {
        // Layout组件特殊处理
        route.component = Layout
      } else {
        route.component = _import(route.component)
      }
    }
    route.label = route.meta.title
    if (route.children && route.children.length > 0) {
      route.alwaysShow = true
      route.children = filterAsyncRouter(route.children)
    }
    if (!route.label) {
      route.alwaysShow = false
    }
    return true
  })
  return extendRouters
}

router.afterEach((to, from) => {
  NProgress.done() // 结束Progress
  if (to.path === '/home' && from.path === '/login') {
    let path = ''
    if ((store.state as any).permission.bigScreenR[0]) {
      path = (store.state as any).permission.bigScreenR[0].path
      router.push(path)
    }
  } else if (to.path === '/home' && from.path === '/' && from.name === null) {
    router.push('/home')
  }
})
